package com.ybwh.outterapi.response;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ybwh.outterapi.anno.OpenApi;
import com.ybwh.outterapi.codec.AppInfoAccesser;
import com.ybwh.outterapi.codec.AppKeyHolder;
import com.ybwh.outterapi.codec.DataCrypto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.nio.charset.StandardCharsets;


@ControllerAdvice
@Slf4j
@AllArgsConstructor
public class EncodeResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    private ObjectMapper objectMapper;

    private DataCrypto dataCrypto;

    private AppInfoAccesser appInfoAccesser;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        if (methodParameter.getContainingClass().getAnnotation(RestController.class) == null
                && methodParameter.getMethodAnnotation(ResponseBody.class) == null) {
            return false;
        }


        //判断class是否存在注解
        if (methodParameter.getContainingClass().getAnnotation(OpenApi.class) != null) {
            return true;
        }
        //判断方法是否存在注解
        return methodParameter.getMethodAnnotation(OpenApi.class) != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
//        System.out.println("response-------->" + body);
        //加密
        log.info("【接受到的数据】encode={}", body);
        String encode = null;
        try {
            encode = objectMapper.writeValueAsString(body);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        byte[] data = dataCrypto.encrypt(appInfoAccesser.getAppSecret(AppKeyHolder.get()), encode.getBytes(StandardCharsets.UTF_8));
        return new String(data, StandardCharsets.UTF_8);
    }

}